package com.example.datamanage.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.example.datamanage.common.CodeEnum;
import com.example.datamanage.common.Result;
import com.example.datamanage.exception.MyException;
import com.example.datamanage.pojo.User;
import com.example.datamanage.pojo.dto.LoginDTO;
import com.example.datamanage.pojo.dto.RegisterDTO;
import com.example.datamanage.pojo.dto.UserDTO;
import com.example.datamanage.pojo.dto.UserSearchDTO;
import com.example.datamanage.service.UserService;
import com.example.datamanage.utils.EmailUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @author 28142
 * @description user controller
 * @date 2023/7/17 10:44
 */
@RestController
@Validated
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private EmailUtils emailUtils;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private PasswordEncoder passwordEncoder;
    /**
     * 登录验证码
     */
    public static String code;

    /**
     * 登录
     * @author 杨雨盛
     * @date 2023/7/21 15:15
     * @param loginDTO
     * @return com.example.datamanage.common.Result
     */
    @PostMapping("/login")
    public Result login(@Valid @RequestBody LoginDTO loginDTO) {
        System.out.println(loginDTO);
        if (!loginDTO.getCode().equals(code)) {
            return Result.error(CodeEnum.CODE_403.getCode(), "验证码不匹配");
        }
        UserDTO login = userService.login(loginDTO);
        return Result.success(login);
    }

    /**
     * 获取登录验证码
     * @author 杨雨盛
     * @date 2023/7/23 6:41
     * @return com.example.datamanage.common.Result
     */
    @GetMapping("/login/code")
    public Result getLoginCode() {
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100, 4, 20);
        lineCaptcha.write("D:\\github\\vue-admin-template-master\\src\\assets\\code.jpg");
        code = lineCaptcha.getCode();
        return Result.success(code);
    }

    /**
     * 注册
     * @author 杨雨盛
     * @date 2023/7/21 15:16
     * @param registerDTO
     * @return com.example.datamanage.common.Result
     */
    @PostMapping("/register")
    public Result register(@Valid @RequestBody RegisterDTO registerDTO) {
        boolean flag = userService.register(registerDTO);
        return flag ? Result.success() : Result.error();
    }

    /**
     * 邮箱注册发送验证码
     * @author 杨雨盛
     * @date 2023/7/21 15:15
     * @param email
     * @return com.example.datamanage.common.Result
     */
    @GetMapping("/register/code/{email}")
    public Result sendRegisterCode(@PathVariable
                                   @NotBlank(message = "邮箱不能为空")
                                   @Email(message = "请输入一个合法邮箱")
                                   String email) {
        // 从redis缓存中读取验证码发送时间，如果超过一分钟，则可以继续发送
        String code = stringRedisTemplate.opsForValue().get(email);
        if (StrUtil.isBlank(stringRedisTemplate.opsForValue().get(email + code))) {
            emailUtils.sendEmail(email);
        } else {
            throw new MyException(CodeEnum.CODE_402.getCode(), "请不要重复发送验证码");
        }
        return Result.success(code);
    }

    /**
     * 分页条件查询
     * @author 杨雨盛
     * @date 2023/7/23 7:01
     * @param pageNum
     * @param pageSize
     * @param searchDTO
     * @return com.example.datamanage.common.Result
     */
    @GetMapping("/page/{pageNum}/{pageSize}")
    public Result findPage(@PathVariable Integer pageNum,
                           @PathVariable Integer pageSize,
                           UserSearchDTO searchDTO) {
        return userService.findPage(pageNum, pageSize, searchDTO);
    }

    /**
     * 添加或修改用户
     * @author 杨雨盛
     * @date 2023/7/23 8:08
     * @param user
     * @return com.example.datamanage.common.Result
     */
    @PostMapping
    public Result saveUser(@Valid @RequestBody User user) {
        return userService.saveUser(user) ? Result.success() : Result.error();
    }

    /**
     * 根据id删除用户
     * @author 杨雨盛
     * @date 2023/7/23 7:06
     * @param id
     * @return com.example.datamanage.common.Result
     */
    @DeleteMapping("/{id}")
    public Result deleteUser(@PathVariable Integer id) {
        System.out.println(id);
        return Result.success();
        // return userService.removeById(id) ? Result.success() : Result.error();
    }

    /**
     * 根据id数组批量删除用户
     * @author 杨雨盛
     * @date 2023/7/23 7:07
     * @param ids
     * @return com.example.datamanage.common.Result
     */
    @DeleteMapping("/batch")
    public Result deleteUsers(@RequestBody List<Integer> ids) {
        return userService.removeByIds(ids) ? Result.success() : Result.error();
    }

    /**
     * 导出用户信息表
     * @author 杨雨盛
     * @date 2023/7/23 7:07
     * @param response
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response) {
        userService.export(response);
    }

    /**
     * 导入用户信息表
     * @author 杨雨盛
     * @date 2023/7/23 7:08
     * @param file
     * @return boolean
     */
    @PostMapping("/import")
    public boolean importData(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<User> users = reader.readAll(User.class);
        System.out.println(users);
        boolean b = userService.saveBatch(users);
        return b;
    }
}
